/**
 * 认证上下文
 * 管理用户认证状态和相关操作
 */
import React, { createContext, useContext, useReducer, useEffect, ReactNode } from 'react';
import { 
  AuthState, 
  UserProfile, 
  Token, 
  LoginRequest, 
  RegisterRequest, 
  ChangePasswordRequest,
  ResetPasswordRequest,
  AuthErrorType 
} from '../types/auth';
import AuthService from '../services/authService';
import { showNotification } from '../utils/notification';
import { permissionWatcher } from '../services/permissionWatcher';

// 认证动作类型
type AuthAction =
  | { type: 'SET_LOADING'; payload: boolean }
  | { type: 'SET_ERROR'; payload: string | null }
  | { type: 'LOGIN_SUCCESS'; payload: { user: UserProfile; token: Token } }
  | { type: 'LOGOUT' }
  | { type: 'UPDATE_USER'; payload: UserProfile }
  | { type: 'SET_PERMISSIONS'; payload: string[] }
  | { type: 'CLEAR_ERROR' };

// 初始状态
const initialState: AuthState = {
  isAuthenticated: false,
  user: null,
  token: null,
  permissions: [],
  loading: false,
  error: null,
};

// 认证reducer
function authReducer(state: AuthState, action: AuthAction): AuthState {
  switch (action.type) {
    case 'SET_LOADING':
      return { ...state, loading: action.payload };
    case 'SET_ERROR':
      return { ...state, error: action.payload, loading: false };
    case 'CLEAR_ERROR':
      return { ...state, error: null };
    case 'LOGIN_SUCCESS':
      return {
        ...state,
        isAuthenticated: true,
        user: action.payload.user,
        token: action.payload.token,
        permissions: action.payload.user.permissions,
        loading: false,
        error: null,
      };
    case 'LOGOUT':
      return {
        ...initialState,
      };
    case 'UPDATE_USER':
      return {
        ...state,
        user: action.payload,
        permissions: action.payload.permissions,
      };
    case 'SET_PERMISSIONS':
      return {
        ...state,
        permissions: action.payload,
      };
    default:
      return state;
  }
}

// 认证上下文类型
interface AuthContextType {
  state: AuthState;
  login: (loginData: LoginRequest) => Promise<void>;
  register: (registerData: RegisterRequest) => Promise<void>;
  logout: () => Promise<void>;
  changePassword: (passwordData: ChangePasswordRequest) => Promise<void>;
  resetPassword: (resetData: ResetPasswordRequest) => Promise<void>;
  updateUser: (userData: UserProfile) => void;
  checkAuth: () => Promise<void>;
  clearError: () => void;
  hasPermission: (permission: string) => boolean;
  hasRole: (roleName: string) => boolean;
  hasAnyPermission: (permissions: string[]) => boolean;
  hasAllPermissions: (permissions: string[]) => boolean;
  hasAnyRole: (roles: string[]) => boolean;
}

// 创建上下文
const AuthContext = createContext<AuthContextType | undefined>(undefined);

// 认证提供者组件
interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [state, dispatch] = useReducer(authReducer, initialState);

  /**
   * 检查认证状态
   */
  const checkAuth = async (): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });

    try {
      if (AuthService.isAuthenticated()) {
        const user = await AuthService.getCurrentUser();
        const token = AuthService.getAccessToken();

        if (token) {
          const tokenData: Token = {
            access_token: token,
            refresh_token: AuthService.getRefreshToken() || '',
            token_type: 'bearer',
            expires_in: 0,
            expires_at: 0
          };

          dispatch({
            type: 'LOGIN_SUCCESS',
            payload: { user, token: tokenData }
          });
        }
      }
    } catch (error) {
      // 认证检查失败，清除状态
      dispatch({ type: 'LOGOUT' });
    } finally {
      dispatch({ type: 'SET_LOADING', payload: false });
    }
  };

  /**
   * 用户登出
   */
  const logout = async (): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });

    try {
      await AuthService.logout();
    } catch (error) {
      console.warn('登出请求失败:', error);
    } finally {
      dispatch({ type: 'LOGOUT' });
    }
  };

  // 初始化时检查认证状态
  useEffect(() => {
    checkAuth();
  }, []);

  // 自动刷新令牌 - 优化版本，避免频繁检查
  useEffect(() => {
    if (!state.isAuthenticated) return;

    // 设置定时器检查token过期时间，而不是在每次状态变更时检查
    const checkTokenInterval = setInterval(() => {
      if (AuthService.isTokenExpiringSoon()) {
        console.log('Token即将过期，开始刷新...');
        AuthService.refreshToken().catch((error) => {
          console.error('Token刷新失败:', error);
          // 刷新失败，登出用户
          logout();
        });
      }
    }, 60000); // 每分钟检查一次

    return () => {
      clearInterval(checkTokenInterval);
    };
  }, [state.isAuthenticated]); // 只在认证状态变更时重新设置定时器

  // 权限监听器初始化 - 优化版本，避免循环调用
  useEffect(() => {
    if (state.isAuthenticated && state.user) {
      // 启动权限监听
      const userPermissions = state.user.permissions || [];
      permissionWatcher.start(userPermissions);

      // 注册权限变更回调 - 避免调用checkAuth导致循环
      const unsubscribe = permissionWatcher.onPermissionChange((newPermissions) => {
        console.log('权限已更新，直接更新权限状态...');
        // 直接更新权限状态，避免重新调用checkAuth
        dispatch({ type: 'SET_PERMISSIONS', payload: newPermissions });

        // 更新本地存储中的用户权限
        const currentUser = state.user;
        if (currentUser) {
          const updatedUser = { ...currentUser, permissions: newPermissions };
          dispatch({ type: 'UPDATE_USER', payload: updatedUser });
        }
      });

      return () => {
        unsubscribe();
        permissionWatcher.stop();
      };
    } else {
      // 用户未登录时停止监听
      permissionWatcher.stop();
    }
  }, [state.isAuthenticated, state.user?.id]); // 只依赖用户ID，避免权限变更导致的循环

  /**
   * 用户登录
   */
  const login = async (loginData: LoginRequest): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });
    dispatch({ type: 'CLEAR_ERROR' });

    try {
      const result = await AuthService.login(loginData);
      
      const token: Token = {
        access_token: result.access_token,
        refresh_token: result.refresh_token,
        token_type: result.token_type,
        expires_in: result.expires_in,
        expires_at: Date.now() + result.expires_in * 1000
      };

      dispatch({ 
        type: 'LOGIN_SUCCESS', 
        payload: { user: result.user, token } 
      });
    } catch (error: any) {
      const message = error.response?.data?.message || '登录失败';
      dispatch({ type: 'SET_ERROR', payload: message });
      throw error;
    }
  };

  /**
   * 用户注册
   */
  const register = async (registerData: RegisterRequest): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });
    dispatch({ type: 'CLEAR_ERROR' });

    try {
      await AuthService.register(registerData);
    } catch (error: any) {
      const message = error.response?.data?.message || '注册失败';
      dispatch({ type: 'SET_ERROR', payload: message });
      throw error;
    } finally {
      dispatch({ type: 'SET_LOADING', payload: false });
    }
  };



  /**
   * 修改密码
   */
  const changePassword = async (passwordData: ChangePasswordRequest): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });
    dispatch({ type: 'CLEAR_ERROR' });

    try {
      await AuthService.changePassword(passwordData);
    } catch (error: any) {
      const message = error.response?.data?.message || '密码修改失败';
      dispatch({ type: 'SET_ERROR', payload: message });
      throw error;
    } finally {
      dispatch({ type: 'SET_LOADING', payload: false });
    }
  };

  /**
   * 重置密码
   */
  const resetPassword = async (resetData: ResetPasswordRequest): Promise<void> => {
    dispatch({ type: 'SET_LOADING', payload: true });
    dispatch({ type: 'CLEAR_ERROR' });

    try {
      await AuthService.resetPassword(resetData);
    } catch (error: any) {
      const message = error.response?.data?.message || '重置密码失败';
      dispatch({ type: 'SET_ERROR', payload: message });
      throw error;
    } finally {
      dispatch({ type: 'SET_LOADING', payload: false });
    }
  };

  /**
   * 更新用户信息
   */
  const updateUser = (userData: UserProfile): void => {
    dispatch({ type: 'UPDATE_USER', payload: userData });
  };



  /**
   * 清除错误
   */
  const clearError = (): void => {
    dispatch({ type: 'CLEAR_ERROR' });
  };

  /**
   * 检查用户是否拥有指定权限
   */
  const hasPermission = (permission: string): boolean => {
    if (!state.isAuthenticated || !state.user) return false;
    return AuthService.hasPermission(permission);
  };

  /**
   * 检查用户是否拥有指定角色
   */
  const hasRole = (roleName: string): boolean => {
    if (!state.isAuthenticated || !state.user) return false;
    return AuthService.hasRole(roleName);
  };

  /**
   * 检查用户是否拥有任一权限
   */
  const hasAnyPermission = (permissions: string[]): boolean => {
    if (!state.isAuthenticated || !state.user) return false;
    return AuthService.hasAnyPermission(permissions);
  };

  /**
   * 检查用户是否拥有所有权限
   */
  const hasAllPermissions = (permissions: string[]): boolean => {
    if (!state.isAuthenticated || !state.user) return false;
    return AuthService.hasAllPermissions(permissions);
  };

  /**
   * 检查用户是否拥有任一角色
   */
  const hasAnyRole = (roles: string[]): boolean => {
    if (!state.isAuthenticated || !state.user) return false;
    return AuthService.hasAnyRole(roles);
  };

  const value: AuthContextType = {
    state,
    login,
    register,
    logout,
    changePassword,
    resetPassword,
    updateUser,
    checkAuth,
    clearError,
    hasPermission,
    hasRole,
    hasAnyPermission,
    hasAllPermissions,
    hasAnyRole,
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

// 自定义Hook
export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};
